{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 问题：什么是 pickling 和 unpickling ？\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "面试官想从这道题中考察面试人什么？\n",
    "所有程序都要处理输入和输出，即IO编程。在IO编程中，输入就是将数据从外面（磁盘、网络）流进内存，输出就是将数据从内存流到外面去。可能你会碰到这样的问题，将一个Python对象序列化为一个字节流，以便将它保存到一个文件、存储到数据库或者通过网络进行传输。\n",
    "\n",
    "Python中特定的序列化模块是pickle，而且它只能用于Python对象。所以，这道题，我们可以谈谈pickle和其它一些对象序列化的区别和优势，以及对象序列化的使用场景。\n",
    "\n",
    "答案\n",
    "模块 pickle 实现了对一个Python对象结构的二进制序列化和反序列化。把变量从内存中变成可存储或传输的过程称之为序列化，反过来，把变量内容从序列化的对象重新读到内存里称之为反序列化。\n",
    "\n",
    "pickling 是将Python对象及其所拥有的层次结构转化为一个字节流的序列化过程，而 unpickling 则是是反序列化。\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 拓展"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "我们先看看这个模块中常用的两个接口dump()和load():\n",
    "\n",
    "dump()：序列化某个包含层次结构的对象，并把序列化对象写入文件\n",
    "dumps(): 把任意对象序列化成一个bytes\n",
    "load()：反序列化数据流\n",
    "import pickle\n",
    "\n",
    "class Foo:\n",
    "    attr = 'A class attribute'\n",
    "\n",
    "file = open('dump.txt', 'wb') # b表示二进制\n",
    "picklestring = pickle.dump(Foo, file) # 序列化一个Python类\n",
    "file.close()\n",
    "\n",
    "f = open('dump.txt', 'rb')\n",
    "d = pickle.load(f) # 反序列化\n",
    "f.close()\n",
    "Python中还有另外一种序列化，即序列化一种更为通用的格式，而不是只能用于Python对象。所以Python中的json模块可以允许JSON序列化和反序列化的标准库模块。我们知道，在网络传输中，JSON的使用非常普遍。那我们就来说说pickle和json方式之间有什么区别。\n",
    "\n",
    "因为JSON是一个文本序列化格式，所以json模块的序列化输出是文本对象（unicode），但是上面说了pickle序列化的输出是二进制字节（bytes）。\n",
    "json模块的序列化的输出JSON是可以直接阅读的，可读性更好，而pickle序列化的输出不能。\n",
    "JSON格式是多语言支持的，广泛的兼容性，所以它能被用于Python以外的系统。pickle所使用的数据格式仅可用于Python。这样做的好处是没有外部标准给该格式强加限制。\n",
    "json模块只能序列化一部分Python内置的类型，不能表示用户自定义的类对象。pickle则能表示大多数对象，包括用户自定义的类。\n",
    "加分点\n",
    "pickle 是个不安全的模块。要记住：永远不要去反序列化不信任的数据。因为pickle在进行反序列化加载时会自动加载相应模块并构造实例对象。如果这个被加载的模块中含有一些恶意数据去让Python执行随意指定的系统命令，那么后果会很严重。因此，一定要保证 pickle 只在相互之间可以信任的情况下进行使用。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 小结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Python标准库非常庞大，所提供的组件库涉及范围十分广泛，这一章中只是列举了几个常用的且面试中常碰到的：\n",
    "\n",
    "数学：random\n",
    "容器数据类型：collections\n",
    "数据序列化：pickle\n",
    "当然还有很多库也是会用到的，比如os，time，csv等等，更多的标准库的使用可以在这里找到。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}